const fs = require('fs')
/*
// 这些是异步代码，异步代码不能保证顺序
// 它是谁先完成就先执行谁
fs.readFile('./file/1.txt', 'utf-8', (err, data) => {
    // 读取到的数据
    console.log(data)
})

fs.readFile('./file/2.txt', 'utf-8', (err, data) => {
    // 读取到的数据
    console.log(data)
})

fs.readFile('./file/3.txt', 'utf-8', (err, data) => {
    // 读取到的数据
    console.log(data)
})
*/

/*
// 如果要保证一定是按顺序读取的
// 那么就先读取1，等1读取完了的回调函数调用时再读取2，等2的回调函数执行完了再读取3，那样一定是按顺序
fs.readFile('./file/1.txt', 'utf-8', (err, data) => {
    // 读取到的数据
    console.log(data)

    fs.readFile('./file/2.txt', 'utf-8', (err, data) => {
        // 读取到的数据
        console.log(data)

        fs.readFile('./file/3.txt', 'utf-8', (err, data) => {
            // 读取到的数据
            console.log(data)
        })
    })
})
*/

// 我为了让异步代码能够按顺序执行，就要嵌套多个回调函数
// 不利于代码的阅读
// 所以可以利用promise对象来解决

// 把异步代码包装到promise对象里即可
/*
let p = new Promise( (resolve, reject) => {

    fs.readFile('./file/1.txt', 'utf-8', (err, data) => {
        // 读取到的数据
        resolve(data)
    })
} )

// .then就是执行它封装的异步代码
// 然后.then里的参数就是异步代码执行后的数据（本质就是resolve里的数据）
p
.then( res => {

    console.log(res) // 1111

    return new Promise( (resolve, reject) => {

        fs.readFile('./file/2.txt', 'utf-8', (err, data) => {
            // 读取到的数据
            resolve(data)
        })
    } )
})
.then( res => {

    console.log(res) // 2222
} )
*/


// 我们发现，上面代码确实可以解决回调地狱，但是每次return的promise代码冗余
// 所以还要做封装



/*
function myAxios(url) {

    return new Promise((resolve, reject) => {

        fs.readFile(url, 'utf-8', (err, data) => {
            // 读取到的数据
            resolve(data)
        })
    })
}
myAxios('./file/1.txt')
    .then(res => {

        console.log(res) // 111
        return myAxios('./file/2.txt')
    })
    .then(res => {

        console.log(res) // 222
        return myAxios('./file/3.txt')
    })
    .then (res => {

        console.log(res) // 3333
    })
*/

// 此时就解决了回调地狱的问题
// 但是也依然有回调函数，没有变的像同步一样，所以这时候再用await优化
function myAxios(url) {

    return new Promise((resolve, reject) => {

        fs.readFile(url, 'utf-8', (err, data) => {
            if (err) {
                reject()
                return
            }
            // 读取到的数据
            resolve(data)
        })
    })
}

/*
async function read() {
    // await会自动把右边的promise封装的代码执行完，
    // 并且拿到resolve的数据，相当于就是拿到.then里的数据
    // 但是await必须用在被async修饰的函数里
    // 用await一定会保证要等promise执行完了，才会往下执行
    let res = await myAxios('./file/1.txt')
    console.log(res)

    let res2 = await myAxios('./file/2.txt')
    console.log(res2)
}

read()
*/

// await相当于是一个语法糖
// 它相当于帮你生成的还是promise.then的调用方法
// 所以上面那个代码
// myAxios('./file/1.txt')
// .then( res => {
//     console.log(res)

//     return myAxios('./file/2.txt')
// })
// .then 



// 了解：被async修饰的函数，那么函数的返回值都会被包成promise对象
// 函数如果没写return，也有返回值，只不过返回值是undefined
// async function foo () {

//     return 10
// }
// let pm = foo() 
// console.log(pm) // promise {10}
// pm.then( res => {
//     console.log(res) 
// })


// async function fn () {

//     // await对于异步代码而言，是没作用的
//     // 它有作用的只是被promise封装的代码才有效
//     await setTimeout(() => {
//         console.log('我是异步代码') // 后打印
//     }, 1000)

//     console.log('我在后面') // 先打印
// }

/*
async function fn () {

    // await对于异步代码而言，是没作用的
    // 它有作用的只是被promise封装的代码才有效
    await new Promise((resolve, reject) => {

        setTimeout(() => {
            console.log('我是异步代码') // 先打印
            resolve('xxx')
        }, 1000)
    })

    console.log('我在后面') // 后打印
}

fn()
*/


// 一般情况下，建议使用async和await后，要把代码包装到try catch
// try catch作用：能防止代码报错
// 把可能出错的代码，放到try里面，那样如果报错了不会导致程序无法运行而是进入到catch

// try {

//     console.log(111)
//     console.log(age) 
// }
// catch {

//     console.log('出错会来到这里')
// }

// 很多时候其实代码写的是正确的,但是还是有可能会报错
// 例如读取文件,我的代码绝对不可能写错,但是一定能读到吗??
// 不一定,因为可能这个文件被删了
async function read() {

    // 像这种代码就叫有可能出错的代码,那么规范是建议用try catch包起来
    try {
        let res = await myAxios('./file/1.txt')
        console.log(res)
    }
    catch {

        console.log('代表出错了,再执行一些补救的代码')
    }
}

read()

// 前端中还有哪种情况是代码绝对没问题,但也有可能报错,推荐使用try catch?
// 例如发ajax请求,不一定能正确拿到结果
// 因为有可能你断网了,有可能服务器挂了